package rest.jbpm.filters;

import java.io.StringWriter;
import javax.ws.rs.WebApplicationException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
import java.util.*;

public class JaxbFilter  implements ContainerResponseFilter {
	
    private static final Logger log = LoggerFactory.getLogger(JaxbFilter.class);
    private static final List<String> jaxbPackages = new ArrayList<String>();
    protected static JAXBContext context;
    
    static {
    	try {
            String separatedPackages = "";
            for(String s : new String [] {"rest.jbpm.wrappers",
                                          "rest.jbpm.wrappers.lists",
                                          "rest.jbpm.wrappers.refs"}) {
                separatedPackages += (separatedPackages.isEmpty() ? s : ":" + s);
                jaxbPackages.add(s);
            }
			context = JAXBContext.newInstance(separatedPackages);
		} catch (JAXBException e) {
			e.printStackTrace();
		} 
    }

	@Override
	public ContainerResponse filter(ContainerRequest request,ContainerResponse response) {
		
        // один из наших классов
        if((response.getEntity() != null) &&
                jaxbPackages.contains(response.getEntity().getClass().getPackage().getName())) {

            log.debug("I can write xml myself! Yeah, I dont trust jetty!");
            StringWriter sw = new StringWriter();

            try {

                Marshaller marshaller = context.createMarshaller();
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
                marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
                marshaller.marshal(response.getEntity(), sw);

            } catch (JAXBException e) {
                log.error("failed to serialize JAXB annotated entity");
                throw new WebApplicationException(e);
            }
            response.setEntity(sw.toString());
            request.getQueryParameters().add(ClearNamespaceFilter.CLEANUP, "true");
        }
		return response;
	}

}
